package bu.met.cs664;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * The main class for the Hunt the Wompus game.
 */
public class HuntTheWompus {
	
	/**
	 * Read a board description from a file.
	 * 
	 * @param	filename	the path to the file to read
	 * 
	 * @return	An array of Strings representing the spaces
	 */
	static String[][] ReadBoard(String filename) {
		
		String[][] boardDesc = null;
		
		BufferedReader reader = null;
		
		try {
			reader = new BufferedReader(new FileReader(filename));
			
			String line = "";
			
			while ((line = reader.readLine()) != null) {
				Matcher digitMatcher = Pattern.compile("\\d+").matcher(line);
				
				digitMatcher.find();
				String num0Str = digitMatcher.group();
				int num0 = Integer.valueOf(num0Str);
				
				digitMatcher.find();
				String num1Str = digitMatcher.group();
				int num1 = Integer.valueOf(num1Str);
				
				// All valid lines have 2 numbers.
				if ((num0Str.length() > 0) && (num1Str.length() > 0)) {
				
					// Find the size, which should always precede filling the squares below.
					if (line.toLowerCase().contains("size")) {
						int width = num0;
						int height = num1;
						
						boardDesc = new String[width][height];
	
						for (int y = 0; y < height; y++) {
							for (int x = 0; x < width; x++) {
								boardDesc[x][y] = new String("");
							}
						}
					} else if (boardDesc != null) {
						int x = num0;
						int y = num1;
						
						if (line.toLowerCase().contains("b")) {
							boardDesc[x][y] = boardDesc[x][y].concat("B");
						}
						if (line.toLowerCase().contains("e")) {
							boardDesc[x][y] = boardDesc[x][y].concat("E");
						}
						if (line.toLowerCase().contains("g")) {
							boardDesc[x][y] = boardDesc[x][y].concat("G");
						}
						if (line.toLowerCase().contains("p")) {
							boardDesc[x][y] = boardDesc[x][y].concat("P");
						}
						if (line.toLowerCase().contains("s")) {
							boardDesc[x][y] = boardDesc[x][y].concat("S");
						}
						if (line.toLowerCase().contains("w")) {
							boardDesc[x][y] = boardDesc[x][y].concat("W");
						}
					}
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		return boardDesc;
	}
	
	/**
	 * Play Hunt the Wompus
	 * 
	 * @param	args	N/A
	 */
	public static void main(String[] args) {

		int[] startPosition = {0, 0}; // Assume since the example does not specify.

		String[][] boardDesc = ReadBoard("src/levels/example.txt");
		
		//Board board = new Board(boardDesc.length, boardDesc[0].length); // display an unexplored board
		Board board = new Board(boardDesc); // display the secret board
		
		int boardLength = boardDesc.length; // bug in AgentPlayer/MoveEvaluator which only takes one dim.
		
		if (boardLength < boardDesc[0].length){
			boardLength = boardDesc[0].length;
		}
		
		//Player player = new HumanPlayer(startPosition); // skip the AI to manually test
        Player player = new AgentPlayer(boardLength, startPosition, Direction.NORTH);
		
		int turn = 1;
		int score = 0;
		boolean hasLeft = false;
		boolean hasDied = false;
		
		System.out.println("Player enters");
		
		board.print(startPosition);

		while (!hasLeft && !hasDied) {
			System.out.println("");

			int[] move = player.nextMove(board);
			
			if (move != null) {
				score--; // Any move reduces the score by 1.
				
				// If the player dies, 1000 points are lost.
				if (boardDesc[move[0]][move[1]].toLowerCase().contains("p") ||
					boardDesc[move[0]][move[1]].toLowerCase().contains("w")) {
					score -= 1000;
					hasDied = true;
				}
				
				board.print(move);
			} else {
				hasLeft = true;
			}
			
			turn++;
		}
		
		// If the player shot the arrow, it cost 10 points.
		if (!player.hasArrow()) {
			score -= 10;
		}
		
		// If the player escapes with the gold, 1000 points are gained.
		if (hasLeft) {
			if (player.hasGold()) {
				score += 1000;
			}
			
			System.out.println("Player leaves with a score of " + score);			
		}
		else
		{
			System.out.println("Player dies with a score of " + score);
		}
	}
}